package com.gl.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.gl.pojo.dto.*;
import com.gl.exception.BusinessException;
import com.gl.mapper.UserMapper;
import com.gl.pojo.entity.User;
import com.gl.pojo.vo.UserPageVo;
import com.gl.service.UserService;
import com.gl.utils.AliyunOSSOperator;
import com.gl.utils.CurrentHolder;
import com.gl.utils.JwtUtils;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements UserService {

    private final String fromEmail = "1992201300@qq.com";
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private JavaMailSender mailSender;
    @Autowired
    private AliyunOSSOperator aliyunOSSOperator;

    @Override
    public UserRegisterResponse register(UserRegisterRequest request) {
        // 校验用户名唯一性
        if (userMapper.existsByUsername(request.getUsername())) {
            throw new BusinessException("用户名已存在");
        }

        // 校验邮箱唯一性
        if (userMapper.existsByEmail(request.getEmail())) {
            throw new BusinessException("邮箱已注册");
        }

        // 验证码检验
//        // 获取redis里面的验证码
//        String captcha = redisTemplate.opsForValue().get(request.getEmail());
//        // 验证
//        if (captcha.isEmpty() || !request.getCaptcha().equals(captcha)) {
//            throw new BusinessException("验证码错误或已过期");
//        }
        if (!checkCaptcha(request.getCaptcha(), request.getEmail())) {
            throw new BusinessException("验证码错误或已过期");
        }
        // 删除redis中的验证码
        redisTemplate.delete(request.getEmail());


        // 创建用户对象
        User user = new User();
        user.setId(UUID.randomUUID().toString());
        user.setUsername(request.getUsername());
        user.setEmail(request.getEmail());
        user.setPassword(request.getPassword());
        user.setAvatarUrl(generateDefaultAvatar());

        // 保存到数据库
        if (userMapper.insert(user) != 1) {
            throw new BusinessException("用户注册失败");
        }

        return convertToResponse(user);
    }

    @Override
    public UserLoginResponse login(String email, String password) {
        User user = userMapper.selectByEmailAndPassword(email, password);
        if (user == null) {
            throw new BusinessException("登录失败，邮箱或密码错误");
        }
        //生成token
        Map<String, Object> map = new HashMap<>();
        map.put("uid", user.getId());
        map.put("username", user.getUsername());
        String token = JwtUtils.generateToken(map);
        //封装response
        UserLoginResponse response = new UserLoginResponse();
        response.setId(user.getId());
        response.setUsername(user.getUsername());
        response.setAvatarUrl(user.getAvatarUrl());
        response.setToken(token);
        return response;
    }

    /**
     * 验证码
     *
     * @param email 邮箱
     */
    @Override
    public void captcha(String email) {
        //1. 生成验证码
        String captcha = RandomStringUtils.randomNumeric(6);
        //2. 发送验证码到邮箱
        try {
            MimeMessage message = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);

            helper.setFrom(fromEmail);
            helper.setTo(email);
            helper.setSubject("注册验证码");
            helper.setText("<h3>您的验证码是：<span style='color:red'>" + captcha + "</span></h3>", true);

            mailSender.send(message);
        } catch (MessagingException e) {
            throw new BusinessException("邮件发送失败");
        }
        //3. 将验证码保存到redis中，并设置过期时间
        redisTemplate.opsForValue().set(email, captcha, 5, TimeUnit.MINUTES);
    }

    /**
     * 根据用户ID查询用户信息
     *
     * @param userId 用户ID
     * @return -
     */
    @Override
    public User selectById(String userId) {
        if (userId == null) return null;
        return userMapper.selectByUserId(userId);
    }

    /**
     * 分页查询用户信息
     *
     * @param userPage 用户信息
     * @return -
     */
    @Override
    public UserPageVo page(UserPageDto userPage) {
        if (userPage.getPage() == null || userPage.getPageSize() == null) {
            throw new BusinessException("分页参数错误");
        }

        PageHelper.startPage(userPage.getPage(), userPage.getPageSize());
        Page<User> result = (Page<User>) userMapper.page(userPage.getUsername());
        // 获取分页结果
        List<User> users = result.getResult();
        long total = result.getTotal();
        // 封装
        UserPageVo userPageVo = new UserPageVo();
        userPageVo.setList(users);
        userPageVo.setTotal(total);

        return userPageVo;
    }

    /**
     * 删除用户
     *
     * @param userId 用户ID
     */
    @Override
    public void deleteById(String userId) {
        if (userId == null) return;
        userMapper.deleteById(userId);
    }

    /**
     * 更新用户所有信息
     *
     * @param user 用户
     */
    @Override
    public void updateUser(User user) {
        if (user.getId() == null) return;
        userMapper.updateUser(user);
    }

    @Override
    public boolean identifyPassword(User user) {
        if (user == null || user.getId() == null) return false;
        String userId = CurrentHolder.getCurrentId();
        User temp = userMapper.selectByUserId(userId);
        // 密码验证成功
        if (temp.getPassword().equals(user.getPassword())) {
            // 发送邮箱
            captcha(temp.getEmail());
            return true;
        }
        // 密码验证失败
        return false;
    }

    @Override
    public boolean identifyCaptcha(String email, String captcha) {
        if (captcha == null || captcha.isEmpty()) return false;
        if (!checkCaptcha(captcha, email)) {
            throw new BusinessException("验证码错误或已过期");
        }
        return true;
    }

    @Override
    public void updateAvatar(MultipartFile file) {
        //获取用户原有URL
        User user = userMapper.selectByUserId(CurrentHolder.getCurrentId());
        String userAvatarURL = user.getAvatarUrl();
        //根据URL删除头像
        if (userAvatarURL != null) {
            try {
                aliyunOSSOperator.deleteImageByUrl(userAvatarURL);
            } catch (Exception e) {

            }
        }
        //上传新的头像
        String fileUrl;
        try {
            fileUrl = aliyunOSSOperator.upload(file.getBytes(), file.getOriginalFilename());
        } catch (Exception e) {
            throw new BusinessException("头像更新失败");
        }
        //更新头像URL
        User tempUser = new User();
        tempUser.setId(CurrentHolder.getCurrentId());
        tempUser.setAvatarUrl(fileUrl);
        userMapper.updateUser(tempUser);
    }


    // 从这里开始是私有方法
    private String generateDefaultAvatar() {
        // 实现默认头像生成逻辑
        return "https://example.com/avatar/default.png";
    }

    /**
     * 校验验证码
     *
     * @param captcha 验证码
     * @param email 邮箱
     * @return -
     */
    private Boolean checkCaptcha(String captcha, String email) {
        if (captcha == null || email == null || captcha.isEmpty() || email.isEmpty()) {
            return false;
        }
        // 从Redis中获取验证码
        String storedCaptcha = redisTemplate.opsForValue().get(email);
        // 比较验证码
        return captcha.equals(storedCaptcha);
    }

    private UserRegisterResponse convertToResponse(User user) {
        UserRegisterResponse response = new UserRegisterResponse();
        response.setId(user.getId());
        response.setUsername(user.getUsername());
        response.setEmail(user.getEmail());
        response.setAvatarUrl(user.getAvatarUrl());
        return response;
    }
}
